package Arithmetic2;
//-----------------------------------------------------------
//   Calculate.java      Java Foundations
//
//   计算后缀表达式
//------------------------------------------------------------
import java.util.Stack;
import java.util.StringTokenizer;

public class Calculate {
  /** constant for addition symbol */
  private final char ADD = '+';
  /** constant for subtraction symbol */
  private final char SUBTRACT = '-';
  /** constant for multiplication symbol */
  private final char MULTIPLY = '*';
  /** constant for division symbol */
  private final char DIVIDE = '/';
  /** the stack */
  private Stack<String> stack;
  private RationalNumber s1,s2;

  public Calculate() {
    stack = new Stack<String>();
  }

  //用栈的方法进行多个单次计算
  public String evaluate (String expr) {
    RationalNumber computingresult = null;
    String op1, op2,result = "";
    int numer1, denom1,numer2,denom2;
    String token;
    StringTokenizer tokenizer = new StringTokenizer(expr);

    while (tokenizer.hasMoreTokens()) {
      token = tokenizer.nextToken();

      if (isOperator(token)) {
        op1 = stack.pop();
        op2 = stack.pop();

        StringTokenizer tokenizer1 = new StringTokenizer(op2, "/");
        numer1 = Integer.parseInt(tokenizer1.nextToken());
        if (tokenizer1.hasMoreTokens())
          denom1 = Integer.parseInt(tokenizer1.nextToken());
        else denom1 = 1;
        s1 = new RationalNumber(numer1,denom1);

        StringTokenizer tokenizer2 = new StringTokenizer(op1, "/");
        numer2 = Integer.parseInt(tokenizer2.nextToken());
        if (tokenizer2.hasMoreTokens())
          denom2 = Integer.parseInt(tokenizer2.nextToken());
        else denom2 = 1;
        s2 = new RationalNumber(numer2,denom2);

        computingresult = CalculateOp(token.charAt(0),s1,s2);
        stack.push(computingresult.toString());
      }else
        stack.push(token);
    }
    result = stack.pop();
    return result;
  }

  //符号匹配方法
  private boolean isOperator (String token){
    return ( token.equals("+") || token.equals("-") ||
            token.equals("*") || token.equals("/") );
  }

  //具体计算类
  private RationalNumber CalculateOp(char operation, RationalNumber op1, RationalNumber op2)
  {
    RationalNumber result = null;
    switch (operation)
    {
      case ADD:
        result = op1.add(op2);
        break;
      case SUBTRACT:
        result = op1.subtract(op2);
        break;
      case MULTIPLY:
        result = op1.multiply(op2);
        break;
      case DIVIDE:
        result = op1.divide(op2);
        break;
    }
    return result;
  }
}
